/**
 * @file RecordType.c
 * @author 严一涵 (yyhhenry@foxmail.com)
 * @brief 借阅记录类型
 * @version 0.1
 * @date 2022-05-14
 *
 * @copyright Copyright (c) 2022
 *
 */
#include "./RecordType.h"

const char *const RecordSheetTitle = "图书编码,借阅人编码,借阅日期,归还日期";

RecordType *RecordType_RecordType(const char *str)
{
    ListType *list = Str_split(str, ",", 0);
    ListNode *ite = list->head;
    RecordType *record = malloc(sizeof(RecordType));
    record->bookId = Str_clone(Str_ListNode(ite)), ite = ite->next;
    record->userId = Str_clone(Str_ListNode(ite)), ite = ite->next;
    record->startDate = Str_clone(Str_ListNode(ite)), ite = ite->next;
    record->endDate = Str_clone(Str_ListNode(ite)), ite = ite->next;
    ListType_free(list);
    return record;
}

RecordType *RecordType_ListNode(ListNode *p)
{
    return p->ptr;
}

char *RecordType_toCSVStr(RecordType *record)
{
    ListType *list = ListType_ListType(free);
    ListType_insert(list, NULL, Str_CSVMode(record->bookId));
    ListType_insert(list, NULL, Str_CSVMode(record->userId));
    ListType_insert(list, NULL, Str_CSVMode(record->startDate));
    ListType_insert(list, NULL, Str_CSVMode(record->endDate));
    char *res = Str_join(list, ",");
    ListType_free(list);
    return res;
}

void RecordType_free(void *_record)
{
    RecordType *record = _record;
    free(record->bookId);
    free(record->userId);
    free(record->startDate);
    free(record->endDate);
    free(record);
}

RecordListType *RecordListType_RecordListType(const char *_filename)
{
    RecordListType *recordList = malloc(sizeof(RecordListType));
    recordList->filename = Str_clone(_filename);
    recordList->list = ListType_ListType(RecordType_free);
    RecordListType_read(recordList);
    return recordList;
}

void RecordListType_free(RecordListType *recordList)
{
    free(recordList->filename);
    ListType_free(recordList->list);
    free(recordList);
}

void RecordListType_read(RecordListType *recordList)
{
    char *fileContent = Str_fromFile(recordList->filename);
    ListType *tmpList = Str_split(fileContent, "\n", 1);
    while (recordList->list->size)
        ListType_remove(recordList->list, recordList->list->head);
    ListType_remove(tmpList, tmpList->head); // 删去表头
    while (tmpList->size)
    {
        char *tmpStr = Str_ListNode(tmpList->head); // 借用所有权，不销毁
        if (!Str_isSpace(tmpStr))
            ListType_insert(recordList->list, NULL, RecordType_RecordType(tmpStr));
        ListType_remove(tmpList, tmpList->head);
    }
    free(fileContent);
    ListType_free(tmpList);
}

void RecordListType_write(RecordListType *recordList)
{
    ListType *tmpList = ListType_ListType(free);
    ListType_insert(tmpList, NULL, Str_clone(RecordSheetTitle));
    for (ListNode *ite = recordList->list->head; ite; ite = ite->next)
    {
        ListType_insert(tmpList, NULL, RecordType_toCSVStr(RecordType_ListNode(ite)));
    }
    char *fileContent = Str_join(tmpList, "\n");
    Str_toFile(fileContent, recordList->filename);
    free(fileContent);
    ListType_free(tmpList);
}

ListType *RecordListType_queryUser(RecordListType *recordList, const char *userId)
{
    ListType *res = ListType_ListType(Ref_free);
    for (ListNode *ite = recordList->list->head; ite; ite = ite->next)
    {
        if (strcmp(RecordType_ListNode(ite)->userId, userId) == 0)
            ListType_insert(res, NULL, ite->ptr);
    }
    return res;
}

ListNode *RecordListType_query(RecordListType *recordList, const char *bookId, const char *userId)
{
    for (ListNode *ite = recordList->list->head; ite; ite = ite->next)
    {
        RecordType *record = RecordType_ListNode(ite);
        if (strcmp(record->bookId, bookId) == 0 && strcmp(record->userId, userId) == 0)
            return ite;
    }
    return NULL;
}

void RecordListType_borrow(RecordListType *recordList, BookListType *bookList, AccountListType *accountList, const char *bookId, const char *userId)
{
    BookType *book = BookType_ListNode(BookListType_queryById(bookList, bookId));
    AccountType *account = AccountType_ListNode(AccountListType_query(accountList, userId));
    account->count++;
    book->currentQuantity--;
    RecordType *record = malloc(sizeof(RecordType));
    record->bookId = Str_clone(bookId);
    record->userId = Str_clone(userId);
    record->startDate = Date_getTime(0);
    record->endDate = Date_getTime(30);
    ListType_insert(recordList->list, NULL, record);
    AccountListType_write(accountList);
    BookListType_write(bookList);
    RecordListType_write(recordList);
}

void RecordListType_return(RecordListType *recordList, BookListType *bookList, AccountListType *accountList, const char *bookId, const char *userId)
{
    BookType *book = BookType_ListNode(BookListType_queryById(bookList, bookId));
    AccountType *account = AccountType_ListNode(AccountListType_query(accountList, userId));
    account->count--;
    book->currentQuantity++;
    ListNode *recordNode = RecordListType_query(recordList, bookId, userId);
    ListType_remove(recordList->list, recordNode);
    AccountListType_write(accountList);
    BookListType_write(bookList);
    RecordListType_write(recordList);
}

void RecordListType_continue(RecordListType *recordList, BookListType *bookList, AccountListType *accountList, const char *bookId, const char *userId)
{
    RecordType *record = RecordType_ListNode(RecordListType_query(recordList, bookId, userId));
    record->endDate = Date_getTime(30);
    RecordListType_write(recordList);
}
